<script setup lang="ts">
import type { PlusDialogFormInstance } from "plus-pro-components";
import { reactive, ref, nextTick } from "vue";
import { message } from "@/utils/message";
import {
  formData,
  getFormColumns,
  formRules,
  formDataTransform
} from "./utils/hooks";
import $request from "./utils/request";

// 定义事件
const emit = defineEmits(["ok"]);

// 状态参数
const state = reactive({
  // 当前编辑的ID
  id: undefined,
  // 弹窗标题
  dialogTitle: "",
  // 表单配置
  formColumns: [],
  // 是否显示
  visible: false,
  // 提交中
  confirmLoading: false
});

// 模态框开启数据
const formOptions = ref<FormModalOptions>();

// 组件
const plusDialogFormRef = ref<PlusDialogFormInstance | null>();

// 弹窗开启
const handleOpen = async (options: FormModalOptions) => {
  formOptions.value = options;
  state.formColumns = getFormColumns(options);
  state.id = options?.id;
  if (options?.id) {
    // 编辑
    state.dialogTitle = "编辑菜单";
  } else {
    // 新增
    state.dialogTitle = "新增菜单";
  }
  const data = await formDataTransform.initForm(options);
  if (data !== false) {
    formData.value = data as any;
    state.visible = true;
  }
};

// 弹窗取消
const handleCancel = async () => {
  state.visible = false;
  await nextTick();
  state.formColumns = [];
  plusDialogFormRef.value?.formInstance.clearValidate();
};

// 弹窗提交
const handleSubmit = async () => {
  try {
    state.confirmLoading = true;
    const data = await formDataTransform.transForm(
      formOptions.value,
      formData.value
    );
    if (!state.id) {
      await $request.post.create(data);
      message("创建成功", { type: "success" });
    } else {
      await $request.put.update(state.id, data);
      message("更新成功", { type: "success" });
    }
    handleCancel();
    emit("ok");
  } finally {
    state.confirmLoading = false;
  }
};

defineExpose({
  handleOpen
});
</script>

<template>
  <plus-dialog-form
    ref="plusDialogFormRef"
    v-model:visible="state.visible"
    v-model="formData"
    :form="{
      columns: state.formColumns,
      labelWidth: '105px',
      labelPosition: 'right',
      rules: formRules,
      rowProps: { gutter: 15 },
      colProps: { span: 12 }
    }"
    :dialog="{
      title: state.dialogTitle,
      width: '700px',
      top: '12vh',
      closeOnClickModal: true,
      confirmLoading: state.confirmLoading
    }"
    @confirm="handleSubmit"
    @cancel="handleCancel"
  />
</template>

<style lang="scss" scoped>
//
</style>
